#include "Debug.h"
#include "ShapeProjection.h"


ShapeProjection::ShapeProjection(void)
{
}


ShapeProjection::~ShapeProjection(void)
{
}

void ShapeProjection::map(MSelectionList Sel, Options* opts)
{
	currSel = Sel;
	//cout << "currSell length:" << Sel.length() <<endl;	

	extractVerts();
	boundingBox = new BoundingBox(allVerts);

	if(opts->type == opts->PLANAR)
		projShape = new Plane(boundingBox);
	else if(opts->type == opts->CYLINDRICAL)
		projShape = new Cylinder(boundingBox);

	
	//for all objects selected
	for(int i=0; i<allVerts.size(); i++)
	{
		allVerts.at(i)->reset();
		setUVsForObject(allVerts.at(i), projShape, opts);		
	}
}

void ShapeProjection::setUVsForObject(MItMeshVertex* verts, ProjectionShape* projShape, Options* opts)
{
	MString* mapname = new MString(opts->mapName.c_str());
	while(!verts->isDone())
	{
		float2 uv;
		projShape->getUnscaledUVs(verts->position(MSpace::kWorld), uv);			
		verts->next();
	}	 
	

	cout << "bbound" << projShape->getBottomBound() << endl;
	cout << "tbound" << projShape->getTopBound() << endl;
	cout << "rbound" << projShape->getRightBound() << endl;
	cout << "lbound" << projShape->getLeftBound() << endl;
	cout << "New Height:" << projShape->getHeight() << endl;
	cout << "New Width:" << projShape->getWidth() <<endl;

	setUpUVScale();
	verts->reset();
	while(!verts->isDone())
	{
		MFloatArray uArray;
		MFloatArray vArray;
		MIntArray faceIDs;
		float2 uv;

		verts->getUVs(uArray, vArray, faceIDs);
		verts->getConnectedFaces(faceIDs);
		uArray.setLength(faceIDs.length());
		vArray.setLength(faceIDs.length());

		projShape->getUnscaledUVs(verts->position(MSpace::kWorld), uv);	
		uv[0] = (float)((uv[0]+uAdjust) * uScale);
		uv[1] = (float)((uv[1]+vAdjust) * vScale);

		for(uint i=0; i<faceIDs.length(); i++)
		{
			uArray.set(uv[0], i);
			vArray.set(uv[1], i);
		}

		cout << "Coords: (" << verts->position(MSpace::kWorld).x << "," << verts->position(MSpace::kWorld).y << ") --> (" << uv[0] <<  "," << uv[1] << ")" << endl; 

		verts->setUVs(uArray, vArray, faceIDs, mapname);			
		verts->next();
	}
	
}

void ShapeProjection::extractVerts()
{
	MObject component;
	MDagPath node;

	for(uint i=0; i<currSel.length(); i++)
	{
		currSel.getDependNode(i, component);
		currSel.getDagPath(i, node, component);
		MItMeshVertex* vertexIt = new MItMeshVertex(node, component);
		allVerts.push_back(vertexIt);
	}	
}

void ShapeProjection::setUpUVScale()
{	
	double widthToHeightRatio = projShape->getWidthToHeightRatio();

	uScale = 1 / projShape->getWidth();
	vScale = 1 / projShape->getHeight();

	if(widthToHeightRatio < 1)	
		vScale = vScale * widthToHeightRatio;	
	else	
		uScale = uScale / widthToHeightRatio; 		

	uAdjust = projShape->getLeftBound() * -1;
	vAdjust = projShape->getBottomBound() * -1;

	//cout << "uAdjust: " << uAdjust <<endl;
	//cout << "vAdjust: " << vAdjust <<endl;
	//cout << "uScale: " << uScale <<endl;
	//cout << "vScale: " << vScale <<endl;
}